если тебе звук нужен только для обладателя героя, то ты используешь вместо current camera view
position of hero[GetPlayerId(GetLocalPlayer())]
где hero - массив героев, индекс это номер игрока начиная с нуля
то есть hero[0] красный геро, hero[1] синий и т.д.
тогда это вернет позицию локального героя, а если герой не существует то центр карты
Странное понимание механики. Не бывает универсального лучшего способа, потому и существуют разные способы для конкретных ситуаций.
А экономить байты и такты процессора, заранее пользуясь интерпретируемым скриптовым языком, это вообще моветон.
Разве массив в WarCraft III не предынициализирует 8192 ячейки памяти (по Вашей формуле, в моём случае он потребляет 8192*4=32768 байт, то есть 32Кб)? Он ведь не динамический.
Нет, он динамический. Исходный размер при создании - 1024. И расширяется на 1024 ячейки по мере доступа вплоть до максимальных 8192.
примергде-то надо еще таймером будет. просто по идее система работает так: происходит событие изменения ресурса (запоминаем сколько), следом происходит основное событие (покупка-продажа). значит, здесь ловим итем, потом вычисления с налогами. Но такой порядок бывает не всегда. Вот допустим продажа: сначала продаем (итем забирают, событие продажи), потом дают деньги (событие изменения ресурса). как видишь, здесь надо тогда таймером через 0.00 сек или сколько то сек проверять измену реса
хотел реализовать похожую систему (проводить торговлю не через чат, а через кнопочки). только на мем хаке. изменить можно только в мем хаке. если вы изменяете цену типу предмета, тогда она у всех итемов данного типа меняется. сделал так: копию на каждого игрока, у одного будет одна цена, у другого другая. короче каждый игрок товар может предложить по разной цене. как это будет работать пока не знаю (я не все продумал, и поэтому не доделал).
можно стоимость убрать и триггерами начислять/убавлять
Bergi_Bear, не знаю, я так понимаю, что редактор кампаний как-то по особому позволяет редактировать карту. Насколько помню, изменения карты, что вносятся через редактор кампаний, не влияют на саму карту.
Через тип текстуры земли или как там трава называется.
За кругом используешь ту, которой нет в игровой зоне. Если юнит находиться на ней, то твои действия.
Smart096, баг только в этой карте?
в новых картах бага нету?
если да то стоит проверить импортируемые модели и текстуры (мб часть битая)
но с вероятностью в 60% проблема в системе ибо было много жалоб на баги в вин10
У твоей модели, которая добавляется, вероятно есть нестандартные текстуры. Нужно правильно расположить модель относительно ее текстур. Насколько я помню, я их располагал в одну папку и, вроде как, работало.
По коду честно говоря ничего не понятно. Но в отлове урона это обычная ошибка, когда урон наносится внутри триггера, отлавливающего урон или если он вызывает действия которые наносят урон и снова вызывают этот триггер. Бесконечная рекурсия в общем роняет игру.
Вот обновленная версия на структурах, я её вроде выкладывал...
либо используйте CreateCreepOfType для создания крипов, так будет респаунить тока тех крипов которых вы создали этой функцией...
pro100master, не самый лучший вариант
куча таймеров может вызвать тормоза
лучше использовать 1 периодический таймер и им просто перебирать список умерших юнитов
делаешь области примерно x1 на y1 (точка) у каждой декорации, когда приходишь фиксируешь эти точки через set = (центр точки декорации), после функция, которая добавляет БЕ (боевая единица), без русификатора функция "create" и по одной БЕ на каждую точку с ориентировкой на того кто входит в область (так же фиксируй позицию БЕ, которая входит в область), и после всего этого удаляй точки, которые зафиксированы на декор и на БЕ, которая вошла в область.
можно добавит ещё эффект появления на каждой точке у декора, будет красиво)
Alexey103, руки распримите и сделайте триггерную смену анимации, "stand" - при завершении морфа, чтобы небыло death. Для моделей с альтернативными формами, меняются тег анимации, про это есть статьи. Если не получается - смотрите что вы сделали нетак.
так вроде там морф (спец абилка). после естественной смерти юнит морфится (событие смерти никак не отслеживается). И это легко отслеживается через "приводит в действие". используй всегда дебаги, выводи на экран. я тоже не всегда знаю, проверяю
подробные абилки
Феникс 'AHpx' - вызывает феникса (можно указать кол-во вызванных). Появляется рядом с кастером. Может вызвать безграничное число птиц. Но есть один нюанс со фениксом - у него есть способность 'Превращение в феникса' Aphx, которое после гибели превращает яйцо. Эта способность не позволяет призывать больше одной жар-птицы. Нельзя отследить кастера - того кто призвал эту птицу (debug показывает что феникс призывает феникса, то есть он сам себя призвал) Превращение в феникса 'Aphx' - морф работает при смерти. У фенникса каждый раз становится хп меньше (так специально сделали в РО: у феникса отрицательный реген), и когда умрет естественной смертью (не от руки врагов), тогда превращается в яйцо (такой цикл). Яйцо просуществует несколько секунд (можно задать длительность морфа, если задать 0.00 - постоянный морф). После из яйца рождается феникс.
Как минимум можно переносить данные с карты.Но таким образом ты заменишь то,что у тебя в карте.Другим способом по чуть чуть переносишь и ставишь всё как надо (требования всякие).Таким образом тебе как минимум не нужно будет делать описания и хар-ки.Ну или можешь сам их редактировать.В общем,такие дела.
Создаёшь в редакторе ИИ порядок действий, сохраняешь, импортируешь и запускаешь используя триггеры ( действия ИИ) для конкретного игрока (например: синий). Могу если нужно скинуть карту пример.
DracoL1ch, Не понял как я поменяю количество еды приносяший? DracoL1ch, или абилка такой есть? DracoL1ch, или ты имел виду создать типо так но на основе юнита (Сам писал)
set amount = R2I(amount) - R2I(this[u])
if amount < 0 then
set amount = -amount
set rawcode = rawcode + this.count
endif
set abilityId = this.count - 1
set abilityLevel = 4
set currentAbility = rawcode + abilityId
loop
exitwhen amount == 0
if amount >= powersOf2[abilityId * 3 + (abilityLevel - 2)] then
call UnitAddAbility(u, currentAbility)
call SetUnitAbilityLevel(u, currentAbility, abilityLevel)
call UnitRemoveAbility(u, currentAbility)
set amount = amount - powersOf2[abilityId * 3 + (abilityLevel - 2)]
else
set abilityLevel = abilityLevel - 1
if abilityLevel <= 1 then
set abilityId = abilityId - 1
set abilityLevel = 4
set currentAbility = rawcode + abilityId
endif
endif
endloop
Сделал если кому нужно контроль максимальной еды
// RUS: Создаем 8 юнит еду (Каждый шаг увиличивает 2ух-кратный)
//! runtextmacro UnitStart()
//! i CreateUnit("hfoo", "zxF", "ufma", "8", "FOOD", "BTNMonsterLure.blp")
//! runtextmacro UnitEnd()
//! textmacro UnitStart
/* RUS: Тут можно убрать если не стоит (MemoryHack)
//! externalblock extension=lua ObjectMerger $FILENAME$
//! i function CreateUnit(base, prefix, field, count, name, icon)
//! i k = 0
//! i j = 0
//! i for i = 0, (count - 1) do
//! i j = j + 1
//! i createobject(base, prefix .. string.sub(chars, k + 1, k + 1))
//! i makechange(current, "unam", "Unit - " .. name)
//! i makechange(current, "utip", "")
//! i makechange(current, "utub", "")
//! i makechange(current, "unsf", "(+" .. tostring(2^i) .. ")")
//! i makechange(current, "uico", "ReplaceableTextures\\CommandButtons\\" .. icon)
//! i makechange(current, field, 2^i)
//! i k = k + 1
//! i end
//! i end
//! i setobjecttype("units")
//! i chars = "abcdefghijklmnopqrstuvwxyz"
*/
//! endtextmacro
//! textmacro UnitEnd
/* RUS: Тут можно убрать если не стоит (MemoryHack)
//! endexternalblock
*/
//! endtextmacro
globals
constant integer xe_MAX_PLAYERS = 7
// RUS: Контроль еды
constant integer xe_COUNT_FOOD = 8
constant integer xe_RAWCODE_FOOD = 'zxFa'
endglobals
struct Food
private static group array groups[xe_MAX_PLAYERS]
private static integer array powers[xe_COUNT_FOOD]
private static method onInit takes nothing returns nothing
local integer i = 1
set thistype.powers[0] = 1
loop
exitwhen i > xe_COUNT_FOOD
set thistype.powers[i] = thistype.powers[i - 1] * 2
set i = i + 1
endloop
set i = 0
loop
exitwhen i == xe_MAX_PLAYERS
set thistype.groups[i] = CreateGroup()
set i = i + 1
endloop
endmethod
public static method operator []= takes player p, integer i returns nothing
local integer count = xe_COUNT_FOOD - 1
local group g = thistype.groups[GetPlayerId(p)]
local unit u = FirstOfGroup(g)
loop
exitwhen u == null
call RemoveUnit(u)
call GroupRemoveUnit(g, u)
set u = FirstOfGroup(g)
endloop
loop
exitwhen i == 0
if i >= thistype.powers[count] then
call GroupAddUnit(g, CreateUnit(p, xe_RAWCODE_FOOD + count, 0., 0., 0.))
set i = i - thistype.powers[count]
else
set count = count - 1
endif
endloop
set u = null
set g = null
endmethod
endstruct
в 1.26 так делал xgm.guru/p/wc3/163817
Ща mix убраны и архитектура wc переделана, но идея таже - внедриться в процесс варкрафта и найти оффсеты функций.
Насколько я знаю в мемхаке функции достаточно понятным образом называются. Но тем не менее, вот список того что вам может понадобиться. Мне кажется этого хватит для описываемых вами целей.
GetUnitBaseDamage
SetUnitBaseDamage
AddUnitBaseDamage
GetUnitBonusDamage
SetUnitBonusDamage
AddUnitBonusDamage
GetUnitTotalDamage
Я сам не проверял, но они должны выполнять указанную функцию.
А по поводу сохранения - вам понадобится правильная версия pjass, её можно найти в этой статье: xgm.guru/p/wc3/memory-hack, да и вообще в ней все написано про то как запустить мемхак.
И в целом, с мемхаком не нужно слишком сложно думать - нужно просто его поставить, найти нужную функцию и использовать. Благо функции как я уже говорил названы понятным образом.
На сайте, вот тут, есть хорошая статья об этом. Там не совсем то, что вам нужно, но на базе данного примера вы сможете создать всё самостоятельно.
+
И, между прочим, старый форум ещё никто не отменял.
AllChosen, ты пока что не понимаешь, что делаешь.
ты должен вместо цикла с вэйтом использовать "периодичный" таймер и сдвигать координаты, но пока что советуют посмотреть примеры xgm.guru/p/wc3/spellmaker-stomp-spell-creation
есть таймер одноразовый и периодичный, это все один и то же таймер, просто запускает разные режимы. через TimerStart. Вы таймер уже создали так смотрю, теперь нужно ловить запуски таймеров
Наименее ресурсозатратным для игрового процесса будет кастовать саму волну через отдельного дамми, который создаётся специально и только для волны силы. Сама волна наносит 1 ед урона. И потом определив, тип юнит-источника урона - наносим нужный урон от лица героя-хозяина юнита "волна силы".
В варианте "чекать группы каждые 0.0х сек" будет засоряться память и скорее всего будут подлагивания, в варианте со спец-дамиками засорится РО, выбирай из двух зол.
keks_090, чтобы кастовал бот - нужно триггерно приказать ему это сделать. Например, если тот же топот, то действие: Боевая единица - Приказ без цели (Issue Order With No Target), и выбираешь приказ: Вождь минотавров (Орда) - Громовая поступь. Аналогично с другими типами целей и спеллов. Нужно только выбрать приказ способности, на основе которой была создана триггерная способность.
Сделана как триггерная темная стая (гуи). Но с таким же успехом можно переделать под волну силы, огненное дыхание, девятый вал, ледяное дыхание. Все эти абилки похожие только спецэффекты разные.
Есть триггерные действия на смену текстуры в точке, но там тоже есть предел на их количество.
Где-то здесь на хгме был генератор рандомного ландшафта на триггерах, и там случайно выпадает зимний/осенний ланд и т.д.
Когда загружаешь модель, нужно перезагрузить World editor. Если и так не отображаются, может, ты указал неправильный путь к файлам в импорте(смотри видео)
function PolarProjectionX takes real x, real dist, real angle returns real
return x + dist * Cos(angle * bj_DEGTORAD)
endfunction
function PolarProjectionY takes real y, real dist, real angle returns real
return y + dist * Sin(angle * bj_DEGTORAD)
endfunction
function Trig_Hit_Actions takes nothing returns nothing
local unit caster = GetTriggerUnit()
local real face = GetUnitFacing(caster)
local real x = PolarProjectionX(GetUnitX(caster), 100., face)
local real y = PolarProjectionY(GetUnitY(caster), 100., face)
local group targets = CreateGroup()
local unit target
call GroupEnumUnitsInRange(targets, x, y, 100., null)
set target = FindClosestToXY(targets, x, y)
if target != null then
call UnitDamageTargetBJ(caster, target, 100., ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL)
set target = null
endif
set caster = null
call DestroyGroup(targets)
set targets = null
endfunction
The Dude, это несерьезно. Все вопросы описаны в большом количестве статей здесь, на нашем сайте - xgm.guru/p/wc3/articles. То, что перечисляешь не верх мастерства WE, а базовые знания. Материалов предостаточно. Успехов в обучении.
ZeroCaty:
Окей. Я понял, у тебя всё по дефолту. Я имел в виду параметры, которые влияют на то, где, как и когда ИИ строит здание. Немного наврал, там не тип использования, там тип расположения.
вроде как кулдаун не запускается, если в момент применения способности юнита переместить триггером в какое-нибудь другое место (например, на несколько точек вправо)
Я решил это через отслеживание начала заклинания, после чего ставил юнита на паузу на 20 сек с проигрыванием анимации. т.е. способность не завершалась, но выгляедло это так, как будто она завершилась
void - это nothing то есть ничего не возвращает функция, а саму функции называют doTheThing, а unit u - аргументы функции, мануалы про cjass почитай (хотя я тоже соглашусь, что написано очень плохо в мануалах. Нужно попробовать немного самим пописать коды)
можно представить как (если хорошо понимаешь jass)
function doTheThing takes unit u returns nothing
... //что-то делаешь с юнитом u (берем аргумент функции - unit u)
endfunction
GetMyUnit - такой не существует, видимо Док имеет в виду подставить свою переменную
пример
например составил пример функции - определить уровень абилы юнита. Функция называется LV, u - юнит, id - целое число, равкод абилы. Возвращает целое число (уровень абилы).
function LV takes unit u, integer id returns integer
return GetUnitAbilityLevel(u, id)
endfunction
'A000' - равкод абилы
local integer lv = LV(GetTriggerUnit(), 'A000') //узнаем уровень героя
вы мне скинули абсолютно пустую карту с отключенным триггером. А где код? Она у меня норм без проблем запустилась.
вам для работы с lua лучше отказаться от гуи. Вы лишаетесь большого инструмента.
Пример Назарова смотрите с движением снарядов ссылка. там показывают. Ну он же есть. Берете пример prog с хуком, и вставляете триггеры
неправильное событие у вас стоит, тк координаты мыши не получить
это какой то простой код, видимо вы пытаетесь понять как запустить. два показательных примера покажу:
первый - вставляете код
do -- создаём область видимости, чтоб не конфликтовать с другим кодом
local InitGlobalsOrigin = InitGlobals -- хукаем функцию InitGlobals
function InitGlobals()
InitGlobalsOrigin()
-- в этом моменте прошла инициализация карты и можно смело работать
FogEnableOff()
FogMaskEnableOff()
--создаем триггеры
local MouseMove = CreateTrigger( )
TriggerRegisterPlayerMouseEventBJ( MouseMove, Player(0), bj_MOUSEEVENTTYPE_MOVE )
TriggerAddAction( MouseMove, function()
--CreateUnitByName(GetLocalPlayer(),'footman',BlzGetTriggerPlayerMouseX(),BlzGetTriggerPlayerMouseY())
print("координаты: "..BlzGetTriggerPlayerMouseX()..","..BlzGetTriggerPlayerMouseY())
CreateUnit(Player(0),FourCC('hfoo'),BlzGetTriggerPlayerMouseX(),BlzGetTriggerPlayerMouseY(),0)
end)
--end
end
end
второй - с использованием гуи
function onMouseClick()
--CreateUnitByName(GetLocalPlayer(),'footman',BlzGetTriggerPlayerMouseX(),BlzGetTriggerPlayerMouseY())
print("координаты: "..BlzGetTriggerPlayerMouseX()..","..BlzGetTriggerPlayerMouseY())
CreateUnit(Player(0),FourCC('hfoo'),BlzGetTriggerPlayerMouseX(),BlzGetTriggerPlayerMouseY(),0)
end
карта пример прилагается. дело не программе, а в кривых руках)
» WarCraft 3 / Функция GetLocalPlayer()
» WarCraft 3 / Помощь по реализации
» WarCraft 3 / Не работает код (jass)
» WarCraft 3 / Узнать расстояние между юнитами
» WarCraft 3 / Зависание редактора
» WarCraft 3 / Карта не отображается в самом варкрафте
» WarCraft 3 / Баг WURST
» WarCraft 3 / Респавн крипов
» WarCraft 3 / Спавн юнитов при входе в область
» WarCraft 3 / Триггерное превращение?
» WarCraft 3 / Функция ForGroup
» WarCraft 3 / Редактирование иконок
» WarCraft 3 / Кампании
» WarCraft 3 / Функции МемХака
» WarCraft 3 / Добавление зеленого урона.
» WarCraft 3 / Способность прыжок
» WarCraft 3 / Вычисление урона героя
» WarCraft 3 / Триггерная волна силы
» WarCraft 3 / Эффект выстрела остаётся
» WarCraft 3 / Как можно заменить тайл?
» WarCraft 3 / Почему. Просто почему.
» WarCraft 3 / Вопрос по редактору карт
» WarCraft 3 / После применения способности? ИИ застывает.
» WarCraft 3 / Вопрос про UnitDamageTarget?
» WarCraft 3 / Ошибка в коде ИИ